package com.example.finaltool.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.finaltool.annotations.Timer;
import com.example.finaltool.consts.NamePart;
import com.example.finaltool.mapper.SysCorpMapper;
import com.example.finaltool.model.AreaInfo;
import com.example.finaltool.model.Result;
import com.example.finaltool.model.config.Data;
import com.example.finaltool.model.db.SysArea;
import com.example.finaltool.model.db.SysCorp;
import com.example.finaltool.utils.CorpUtils;
import com.example.finaltool.utils.PrintUtils;
import com.example.finaltool.utils.StringUtils;
import com.example.finaltool.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@Service
public class SysCorpService {

    SysAreaService areaService;
    SysCorpMapper mapper;

    @Autowired
    public SysCorpService(SysAreaService areaService,
                          SysCorpMapper mapper) {
        this.areaService = areaService;
        this.mapper = mapper;
    }

    @Timer("sys_corp")
    @Transactional(rollbackFor = Exception.class)
    public void save(Data data, AreaInfo areaInfo) {
        String name = StringUtils.buildName(data);
        String corpId = data.getCorpId();
        List<SysCorp> corps = listZhenSysCorp(corpId);
        if (CollectionUtils.isEmpty(corps)) {
            SysCorp corp = SysCorp.newZhen(name, data, areaInfo);
            mapper.insert(corp);
        }
    }

    @Timer("同步")
    public void enableSync(String corpId) {
        List<SysCorp> corps = listZhenSysCorp(corpId);
        corps.forEach(c -> {
            c.setNeedSync(true);
            mapper.updateById(c);
        });
    }

    private List<SysCorp> listZhenSysCorp(String corpId) {
        QueryWrapper<SysCorp> wrapper = new QueryWrapper<>();
        wrapper.eq("tenant_id", corpId);
        return mapper.selectList(wrapper);
    }

    public Result<String> fillId() {
        PrintUtils.separator();
        PrintUtils.stepStart("区域id补全");
        LocalDateTime start = LocalDateTime.now();
        List<SysCorp> corpList = mapper.getNull();
        AtomicInteger updated = new AtomicInteger();
        StringBuilder fatalName = new StringBuilder();
        corpList.forEach(c -> {
            boolean success = setupSysCorp(c, CorpUtils.toParts(c.getName()));
            if (success) {
                updated.getAndIncrement();
            } else {
                fatalName.append(", ").append(c.getName());
            }
            mapper.updateById(c);
        });
        String res = "更新" + updated + "/" + corpList.size() + "个组织的area_code的id，" + fatalName.toString().replaceFirst(", ", "") + " 由于无法从名称中解析出各级地名，需手动更新";
        log.info(res);
        PrintUtils.stepFinish("区域id补全, 用时" + TimeUtils.duration(start));
        return Result.success(res);
    }

    private boolean setupSysCorp(SysCorp c, Map<String, String> map) {
        if (map.size() == 4) {
            if (c.getProvinceId() == null) {
                c.setProvinceId(1);
            }
            if (c.getCityId() == null) {
                c.setCityId(SysAreaService.shiIdOf(map.get(NamePart.SHI)).intValue());
            }
            SysArea quxian = areaService.getQuxian(map.get(NamePart.QU_XIAN), SysAreaService.shiIdOf(map.get(NamePart.SHI)));
            if (quxian == null) {
                areaService.saveQuxian(map.get(NamePart.SHI), map.get(NamePart.QU_XIAN), SysAreaService.shiIdOf(map.get(NamePart.SHI)));
                quxian = areaService.getQuxian(map.get(NamePart.QU_XIAN), SysAreaService.shiIdOf(map.get(NamePart.SHI)));
            }
            if (c.getDistrictId() == null) {
                c.setDistrictId(quxian.getId().intValue());
            }
            if (c.getVillageId() == null) {
                SysArea zhen = areaService.getZhen(map.get(NamePart.XIANG_ZHEN), quxian.getId());
                if (zhen == null) {
                    areaService.saveZhen(map.get(NamePart.XIANG_ZHEN), quxian.getId());
                    zhen = areaService.getZhen(map.get(NamePart.XIANG_ZHEN), quxian.getId());
                }
                c.setVillageId(zhen.getId().intValue());
            }
            return true;
        } else {
            return false;
        }
    }
}
